package com.hyl.service.impl;

import com.google.common.cache.Cache;
import com.hyl.domain.vo.WeixinTemplateMessageVO;
import com.hyl.domain.req.WeixinQrCodeReq;
import com.hyl.domain.res.WeixinQrCodeRes;
import com.hyl.domain.res.WeixinTokenRes;
import com.hyl.service.weixin.IloginService;
import com.hyl.service.weixin.WeixinApiService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import retrofit2.Call;

import javax.annotation.Resource;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;

/**
 * @author hyl
 * @description 微信服务
 * @create 2025-06-05 16:19
 */
@Service
@Slf4j
public class WeixinLoginServiceImpl implements IloginService {


    @Value("${weixin.config.app-id}")
    private String appid;
    @Value("${weixin.config.app-secret}")
    private String appsecret;
    @Value("${weixin.config.template-id}")
    private String template_id;
    @Resource
    private Cache<String, String> weixinAccessToken;
    @Resource
    private WeixinApiService weixinApiService;
    @Resource
    private Cache<String, String> openidToken;


    @Override
    public String creatQrCodeTicket() throws Exception {

        //1.获取accessToken
        String accessToken = weixinAccessToken.getIfPresent(appid);
        if (accessToken == null){
            Call<WeixinTokenRes> call = weixinApiService.getToken("client_credential", appid, appsecret);
            WeixinTokenRes weixinTokenRes = call.execute().body();
            assert weixinTokenRes != null;
            accessToken = weixinTokenRes.getAccess_token();
            weixinAccessToken.put(appid, accessToken);
        }
        //生成ticket
        WeixinQrCodeReq weixinQrCodeReq = WeixinQrCodeReq.builder()
                .expire_seconds(2592000)
                .action_name(WeixinQrCodeReq.ActionNameTypeVO.QR_SCENE.getCode())
                .action_info(WeixinQrCodeReq.ActionInfo.builder()
                        .scene(WeixinQrCodeReq.ActionInfo.Scene.builder()
                                .scene_id(100601)
                                .build())
                        .build())
                .build();
        Call<WeixinQrCodeRes> call = weixinApiService.createQrCode(accessToken, weixinQrCodeReq);
        WeixinQrCodeRes weixinQrCodeRes = call.execute().body();
        assert weixinQrCodeRes != null;
        return weixinQrCodeRes.getTicket();

    }

    @Override
    public String checkLogin(String ticket) {
        return openidToken.getIfPresent(ticket);
    }

    @Override
    public void saveLoginState(String ticket, String openid) throws IOException {
        // Log the inputs to debug potential nulls
        log.info("saveLoginState called with ticket: '{}', openid: '{}'", ticket, openid);

        if (StringUtils.isBlank(ticket) || StringUtils.isBlank(openid)) {
            // Log an error or throw a more specific exception if these are unexpectedly null/empty
            log.warn("Cannot save login state: ticket or openid is null/empty. Ticket: '{}', OpenID: '{}'", ticket, openid);
            // You might choose to throw an IllegalArgumentException, or simply return if this is an expected scenario.
            // For now, let's just return to prevent the NPE.
            return;
        }

        openidToken.put(ticket, openid); // This is line 85

        String accessToken = weixinAccessToken.getIfPresent(appid);
        if (accessToken == null){
            Call<WeixinTokenRes> call = weixinApiService.getToken("client_credential", appid, appsecret);
            WeixinTokenRes weixinTokenRes = call.execute().body();
            // It's good to also add null checks for weixinTokenRes and its access_token
            if (weixinTokenRes == null || StringUtils.isBlank(weixinTokenRes.getAccess_token())) {
                log.error("Failed to get Weixin access token.");
                return; // Cannot proceed without access token
            }
            accessToken = weixinTokenRes.getAccess_token();
            weixinAccessToken.put(appid, accessToken);
        }

        // 2. 发送模板消息 - Add null check for accessToken before using it
        if (StringUtils.isBlank(accessToken)) {

            return;
        }

        Map<String, Map<String, String>> data = new HashMap<>();
        // Make sure WeixinTemplateMessageVO.put handles null 'openid' gracefully if you don't return above.
        WeixinTemplateMessageVO.put(data, WeixinTemplateMessageVO.TemplateKey.USER, openid);

        WeixinTemplateMessageVO templateMessageDTO = new WeixinTemplateMessageVO(openid, template_id);
        templateMessageDTO.setUrl("https://gaga.plus");
        templateMessageDTO.setData(data);

        Call<Void> call = weixinApiService.sendMessage(accessToken, templateMessageDTO);
        call.execute();
    }
}
